package com.accp.myjson;

import java.lang.reflect.Field;
import java.util.Calendar;
import java.util.Date;

public class JSON {
    /**
     * 将对象转为字符串
     * @param obj 用户传入的对象
     * @return JSON格式的字符串
     */
    public static String toJSON(Object obj){
        String str="{";
        //利用反射回去所有属性
        try {
            Field [] fields=obj.getClass().getDeclaredFields();
            for (Field fd:fields
                 ) {
                //打开私有权限
                fd.setAccessible(true);
                if(fd.getType().getSimpleName().equals("Date")){
                    //获取日期
                    Date date=(Date) fd.get(obj);
                    //日历类 操作日期
                    Calendar cal=Calendar.getInstance();//单例模式
                    //设置日历
                    cal.setTime(date);
                    //拼字符串
                    str+=fd.getName()+":{year:"+cal.get(Calendar.YEAR)
                            +",month:"+cal.get(Calendar.MONTH)
                            +",day:"+cal.get(Calendar.DAY_OF_MONTH)
                            +",hour:"+cal.get(Calendar.HOUR_OF_DAY)
                            +",minute:"+cal.get(Calendar.MINUTE)
                            +",second:"+cal.get(Calendar.SECOND)+"},";
                }
                else{
                    //基本类型，直接获取属性名
                    str+=fd.getName()+":"+fd.get(obj)+",";
                }
            }
            str=str.substring(0,str.length()-1);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        str+="}";
        return str;
    }

    /**
     * 讲json字符串转对象
     * @param json 字符串
     * @param cls 对象类型
     * @param <T>
     * @return
     */
    public static <T>T parseJSON(String json,Class cls){
        Object obj= null;
        try {
            //利用类型信息类建造一个对象
            obj = null;
            obj=cls.newInstance();
            //解析json
            Field [] fields=cls.getDeclaredFields();
            json=json.substring(0,json.length()-1)+",}";
            for (Field fd:fields
            ) {
                fd.setAccessible(true);
                //检查属性在json字符串中是否有匹配的属性名
                if(json.indexOf(fd.getName())!=-1) {
                    //获取属性名在json字符串中的位置
                    int start=json.indexOf(fd.getName());
                    int end=-1;
                    //判断属性的类型
                    if (fd.getType().getSimpleName().equals("Date")) {
                        end=json.indexOf("}",start)+1;
                        //取出对应的字符串
                        String res=json.substring(start,end);
                        //获取日期类的对象
                        //去掉属性名
                        res=res.replace(fd.getName()+":","");
                        //去掉花括号
                        res=res.substring(1,res.length()-1);
                        //以逗号分隔字符串[year:2019,month:5,....]
                        String [] datas=res.split(",");
                        //将子元素再分隔
                        Calendar cal= Calendar.getInstance();
                        int [] vals=new int [6];
                        for (int i = 0;i<datas.length;i++) {
                            //分隔日期
                            vals[i]=Integer.parseInt(datas[i].split(":")[1]);
                        }
                        cal.set(vals[0],vals[1],vals[2],vals[3],vals[4],vals[5]);
                        //填充到目标对象的相应属性中
                        fd.set(obj,cal.getTime());
                    } else {
                        end=json.indexOf(",",start);
                        //取出对应的字符串
                        String res = json.substring(start,end);
                        //分隔字符串并获取值
                        String val=res.split(":")[1];
                        //根据对象属性的类型填充对象
                        if(fd.getType().getSimpleName().equals("int")){
                            fd.setInt(obj,Integer.parseInt(val));
                        }
                        else if(fd.getType().getSimpleName().equals("String")){
                            fd.set(obj,val);
                        }
                    }
                }
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return (T)obj;
    }
}
